// ignore: must_be_immutable
import 'dart:io';

import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:kmxy_base/util/file_util.dart';
import 'package:kmxy_base/util/time_util.dart';

// ignore: must_be_immutable
class Camera extends StatefulWidget {
  late int imageQuality;
  late double? maxWidth;
  late double? maxHeight;
  Camera(
    this.imageQuality, {
    this.maxWidth,
    this.maxHeight,
    super.key,
  });

  @override
  // ignore: library_private_types_in_public_api
  _CameraState createState() => _CameraState();
}

class _CameraState extends State<Camera> {
  late CameraController controller;
  late List<CameraDescription> cameras;

  bool isInit = false;

  double _baseScale = 1.0;
  final double _minAvailableZoom = 1.0;
  final double _maxAvailableZoom = 1.0;
  double _currentScale = 1.0;
  final int _pointers = 0;

  @override
  void initState() {
    super.initState();
    initData();
  }

  initData() async {
    cameras = await availableCameras();
    controller = CameraController(cameras[0], ResolutionPreset.max);
    controller.initialize().then((_) {
      if (!mounted) {
        return;
      }
      setState(() {
        isInit = true;
      });
    });
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (!isInit || !controller.value.isInitialized) {
      return Container();
    }
    return Scaffold(
      backgroundColor: Colors.black,
      body: Column(
        children: [
          Expanded(
              child: CameraPreview(
            controller,
            child: LayoutBuilder(
                builder: (BuildContext context, BoxConstraints constraints) {
              return GestureDetector(
                behavior: HitTestBehavior.opaque,
                onScaleStart: _handleScaleStart,
                onScaleUpdate: _handleScaleUpdate,
                onTapDown: (details) => onViewFinderTap(details, constraints),
              );
            }),
          )),
          Container(
              height: 100.w,
              width: MediaQuery.of(context).size.width,
              color: Colors.black,
              child: Stack(
                alignment: Alignment.center,
                children: [
                  Positioned(
                    left: 30.w,
                    child: InkWell(
                      onTap: _back,
                      child: Icon(
                        Icons.highlight_off,
                        color: Colors.white,
                        size: 40.w,
                      ),
                    ),
                  ),
                  Positioned(
                    child: InkWell(
                      onTap: _camera,
                      child: Icon(
                        Icons.camera,
                        color: Colors.white,
                        size: 60.w,
                      ),
                    ),
                  ),
                ],
              )),
        ],
      ),
    );
  }

  void _handleScaleStart(ScaleStartDetails details) {
    _baseScale = _currentScale;
  }

  Future<void> _handleScaleUpdate(ScaleUpdateDetails details) async {
    // When there are not exactly two fingers on screen don't scale
    if (_pointers != 2) {
      return;
    }

    _currentScale = (_baseScale * details.scale)
        .clamp(_minAvailableZoom, _maxAvailableZoom);

    await controller.setZoomLevel(_currentScale);
  }

  void onViewFinderTap(TapDownDetails details, BoxConstraints constraints) {
    final CameraController cameraController = controller;
    final offset = Offset(
      details.localPosition.dx / constraints.maxWidth,
      details.localPosition.dy / constraints.maxHeight,
    );
    cameraController.setExposurePoint(offset);
    cameraController.setFocusPoint(offset);
  }

  _back() {
    Navigator.pop(context, null);
  }

  _camera() async {
     XFile xFile = await controller.takePicture();
    File? result = await FileUtil.compressImageWithDart(xFile.path,
        '${xFile.path.substring(0, xFile.path.lastIndexOf('/'))}/${TimeUtil.nowTimeMilliseconds()}.jpg',
        quality: widget.imageQuality,
        minHeight: (widget.maxHeight ?? 1920.0).toInt(),
        minWidth: (widget.maxWidth ?? 1080.0).toInt());
    Navigator.pop(context, result.path);
  }
}

class CameraUtil {
  static Future<String?> openCamera(BuildContext context, int imageQuality,
      double? maxWidth, double? maxHeight) async {
    String? path = await Navigator.push(
      context,
      MaterialPageRoute(
        builder: (_) {
          return Camera(
            imageQuality,
            maxWidth: maxWidth,
            maxHeight: maxHeight,
          );
        },
      ),
    );
    return path;
  }
}
